package com.sixkey.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sixkey.constant.CommonConstant;
import com.sixkey.constant.RabbitMQConstant;
import com.sixkey.entity.*;
import com.sixkey.entity.vo.MessageDataVo;
import com.sixkey.entity.vo.ReSignVo;
import com.sixkey.entity.vo.SignDataVo;
import com.sixkey.entity.vo.SignVo;
import com.sixkey.exception.ServiceException;
import com.sixkey.mapper.SignMapper;
import com.sixkey.rabbitmq.RabbitService;
import com.sixkey.response.ResponseEnum;
import com.sixkey.service.IDepartmentService;
import com.sixkey.service.IReservationService;
import com.sixkey.service.ISignService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sixkey.service.IUserService;
import com.sixkey.utils.TimeStringUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户签到表 服务实现类
 * </p>
 *
 * @author author
 * @since 2023-10-25
 */
@Service
public class SignServiceImpl extends ServiceImpl<SignMapper, Sign> implements ISignService {

    @Lazy
    @Autowired
    private IReservationService reservationService;

    @Autowired
    private RabbitService rabbitService;

    @Lazy
    @Autowired
    private IUserService userService;

    @Lazy
    @Autowired
    private IDepartmentService departmentService;

    /**
     * 获取当前用户的所有签到记录
     * @param phone
     * @return
     */
    @Override
    public List<ReSignVo> getSignRecords(String phone) {
        List<Sign> signList = this.list(new QueryWrapper<Sign>().eq("phone", phone));
        //获取所有的会议id
        if(CollectionUtils.isEmpty(signList)){
            return null;
        }
        List<Integer> reservationIds = signList.stream().map(Sign::getReservationId).collect(Collectors.toList());
        List<ReSignVo> list = new ArrayList<>();
        if(CollectionUtils.isEmpty(reservationIds)){
            return null;
        }
        reservationIds.stream().forEach(item -> {
            Reservation reservation = reservationService.getById(item);
            ReSignVo reSignVo = new ReSignVo();
            reSignVo.setTheme(reservation.getTheme());
            String beginTime = TimeStringUtils.getBeginTime(reservation.getBeginTime());
            reSignVo.setBeginTime(beginTime);
            list.add(reSignVo);
        });
        return list;
    }

    /**
     * 用户会议签到
     * @param phone
     * @return
     */
    @Override
    public void toSign(String phone, int id) {
        //防止用户重复签到
        List<Sign> signList = this.list(new QueryWrapper<Sign>().eq("reservation_id", id));
        if(CollectionUtils.isEmpty(signList)){
            //根据会议id查询会议
            Reservation reservation = reservationService.getById(id);
            if(reservation.getStatus().equalsIgnoreCase(CommonConstant.RESERVATION_STATUS_2)){
                throw new ServiceException(ResponseEnum.SIGN_TIMEOUT);
            }
            Sign sign = new Sign();
            sign.setReservationId(id);
            sign.setPhone(phone);
            rabbitService.sendMessage(RabbitMQConstant.EXCHANGE_SIGN,RabbitMQConstant.ROUTING_SIGN,sign);
        }else {
            List<String> phones = signList.stream().map(Sign::getPhone).collect(Collectors.toList());
            //查询当前会议签到记录中是否有签到过的用户
            boolean flag = phones.contains(phone);
            if(flag) {
                throw new ServiceException(ResponseEnum.RESET_SIGN);
            }
            //根据会议id查询会议
            Reservation reservation = reservationService.getById(id);
            if(reservation.getStatus().equalsIgnoreCase(CommonConstant.RESERVATION_STATUS_2)){
                throw new ServiceException(ResponseEnum.SIGN_TIMEOUT);
            }
            Sign sign = new Sign();
            sign.setReservationId(id);
            sign.setPhone(phone);
            rabbitService.sendMessage(RabbitMQConstant.EXCHANGE_SIGN,RabbitMQConstant.ROUTING_SIGN,sign);
        }
    }

    @Override
    public Map<String, Object> queryList(Integer pageNo, Integer pageSize, SignVo signVo) {
        Page<Sign> pageInfo = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<Sign> wrapper = new LambdaQueryWrapper<>();
        //添加过滤条件(模糊查询)
        Reservation reservation = reservationService.getOne(new QueryWrapper<Reservation>().eq("theme", signVo.getTheme()));
        if(null != reservation){
            wrapper.like(!StringUtils.isEmpty(reservation.getId()),Sign::getReservationId,reservation.getId());
        }
        wrapper.like(!StringUtils.isEmpty(signVo.getPhone()),Sign::getPhone,signVo.getPhone());
        //添加排序条件
        wrapper.orderByDesc(Sign::getUpdateTime);
        Page<Sign> signPage = this.page(pageInfo, wrapper);
        //分页的所有数据
        long total = signPage.getTotal();
        List<Sign> records = signPage.getRecords();
        List<SignDataVo> list = new ArrayList<>();
        records.stream().forEach(item -> {
            SignDataVo signDataVo = new SignDataVo();
            User user = userService.getOne(new QueryWrapper<User>().eq("phone", item.getPhone()));
            Department department = departmentService.getById(user.getDeptId());
            Reservation res = reservationService.getById(item.getReservationId());
            signDataVo.setName(user.getName());
            signDataVo.setId(item.getId());
            signDataVo.setPhone(item.getPhone());
            signDataVo.setAvatar(user.getAvatar());
            signDataVo.setDeptName(department.getName());
            signDataVo.setTheme(res.getTheme());
            list.add(signDataVo);
        });
        Map<String,Object> map = new HashMap<>();
        map.put("data",list);
        map.put("total",total);
        return map;
    }

    @Override
    public void saveSign(SignVo signVo) {
        Reservation reservation = reservationService.getOne(new QueryWrapper<Reservation>().eq("theme", signVo.getTheme()));
        if(reservation == null){
            throw new ServiceException(ResponseEnum.RESERVATION_NOT_FOUND);
        }
        Sign sign = new Sign();
        sign.setPhone(signVo.getPhone());
        sign.setReservationId(reservation.getId());
        this.save(sign);
    }

    @Override
    public SignVo getSignById(Integer id) {
        Sign sign = this.getById(id);
        Reservation reservation = reservationService.getById(sign.getReservationId());
        SignVo signVo = new SignVo();
        signVo.setTheme(reservation.getTheme());
        signVo.setPhone(sign.getPhone());
        signVo.setId(sign.getId());
        return signVo;
    }

    @Override
    public void updateSign(Sign sign) {
        Reservation reservation = reservationService.getOne(new QueryWrapper<Reservation>().eq("theme", sign.getTheme()));
        sign.setReservationId(reservation.getId());
        this.updateById(sign);
    }
}
